<script setup lang="ts">
import RoomStatus from './components/RoomStatus.vue'
import RoomAction from './components/RoomAction.vue'
import RoomMessage from './components/RoomMessage.vue'
import { onMounted, onUnmounted } from 'vue'
import { useUserStore } from '@/stores'
import { useRoute } from 'vue-router'
import type { Message } from '@/types/room'
import { MsgType, OrderType } from '@/enums'
import { ref, nextTick, provide } from 'vue'
import type { ConsultOrderItem, Image } from '@/types/consult'
import {
  getConsultOrderDetail,
  getChatMessageList,
  sendChatMessage,
  updateMessageStatus
} from '@/services/consult'
import dayjs from 'dayjs'
import { showToast } from 'vant'
import { getUserInfo } from '@/services/user'

const consult = ref<ConsultOrderItem>()
let currentStatus: number | undefined

const loadConsult = async () => {
  const res = await getConsultOrderDetail(route.query.orderId as string)
  const data = res.data as any
  // 如果返回的是字符串枚举名称，转换为数字后赋值给 consult
  const newStatus =
    typeof data.status === 'string'
      ? OrderType[data.status as keyof typeof OrderType]
      : data.status

  consult.value = {
    ...data,
    status: newStatus,
    statusValue: data.status
  }

  // 检查状态是否变化
  if (currentStatus !== undefined && currentStatus !== newStatus) {
    // 状态发生变化时重新加载消息
    loadChatMessages()
  }
  currentStatus = newStatus
}

// 提供问诊订单数据给后代组件
provide('consult', consult)
const completeEva = (score: number) => {
  const item = list.value.find((item) => item.msgType === MsgType.CardEvaForm)
  if (item) {
    item.msg.evaluateDoc = { score }
    item.msgType = MsgType.CardEva
  }
}
provide('completeEva', completeEva)

const userAvatar = ref('')
const doctorAvatar = ref('')
const userStore = useUserStore()
const route = useRoute()
const list = ref<Message[]>([])
const initialMsg = ref(true)
let pollingTimer: NodeJS.Timeout | null = null

onMounted(async () => {
  const res = await getConsultOrderDetail(route.query.orderId as string)
  const data = res.data as any
  // 如果返回的是字符串枚举名称，转换为数字后赋值给 consult
  const newStatus =
    typeof data.status === 'string'
      ? OrderType[data.status as keyof typeof OrderType]
      : data.status

  consult.value = {
    ...data,
    status: newStatus,
    statusValue: data.status
  }
  if (userAvatar.value === '' && consult.value?.patientInfo?.id) {
    const res = await getUserInfo(consult.value?.patientInfo?.userId)
    userAvatar.value = res.data?.avatar || ''
  }
  if (doctorAvatar.value === '' && consult.value?.doctorId) {
    const res = await getUserInfo(consult.value.doctorId)
    doctorAvatar.value = res.data?.avatar || ''
  }

  // 先创建患者卡片，但先不添加到list中
  const patientCard: Message = {
    id: `patient-card-${Date.now()}`,
    msgType: MsgType.CardPat,
    createdTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    msg: {
      consultRecord: consult.value
    }
  }

  // 将患者卡片添加到list第一位
  list.value.push(patientCard)

  loadConsult()
  startPolling()
})

onUnmounted(() => {
  stopPolling()
})

// 开始轮询
const startPolling = () => {
  // 立即获取一次消息
  loadChatMessages()
  // 设置定时器，每3秒轮询一次消息，每10秒检查一次订单状态
  pollingTimer = setInterval(() => {
    loadChatMessages()
    // 每隔一段时间也检查订单状态
    if (Math.random() < 0.3) {
      // 大约30%的概率检查状态
      loadConsult()
    }
  }, 3000) // 改为3秒轮询一次，避免过于频繁
}

// 停止轮询
const stopPolling = () => {
  if (pollingTimer) {
    clearInterval(pollingTimer)
    pollingTimer = null
  }
}
const fromAvatar = () => {
  const fileName =
    userStore.user?.id === consult.value?.doctorId
      ? doctorAvatar.value
      : userAvatar.value
  return `${import.meta.env.VITE_APP_API_BASE_URL}/public/images/${fileName}`
}
const toAvatar = () => {
  const fileName =
    userStore.user?.id === consult.value?.patientInfo?.id
      ? doctorAvatar.value
      : userAvatar.value
  return `${import.meta.env.VITE_APP_API_BASE_URL}/public/images/${fileName}`
}

// 加载聊天消息
const loadChatMessages = async () => {
  if (!consult.value?.id) return

  try {
    time.value = dayjs().format('YYYY-MM-DD HH:mm:ss')
    const res = await getChatMessageList(consult.value.id, time.value)
    const data = res.data

    if (data && Array.isArray(data) && data.length > 0) {
      const arr: Message[] = []
      data.forEach((item: any) => {
        arr.push({
          ...item,
          msgType: MsgType[item.msgType as keyof typeof MsgType],
          fromAvatar: fromAvatar(),
          toAvatar: toAvatar()
        })
      })

      // 检查是否有新消息
      const hasNewMessages = arr.some(
        (msg) => !list.value.find((existingMsg) => existingMsg.id === msg.id)
      )

      if (hasNewMessages) {
        // 如果是第一次加载或下拉刷新
        if (initialMsg.value || loading.value) {
          // 找到患者卡片并临时移除
          const patientCardIndex = list.value.findIndex(
            (item) => item.msgType === MsgType.CardPat
          )
          let patientCard = null
          if (patientCardIndex !== -1) {
            patientCard = list.value.splice(patientCardIndex, 1)[0]
          }

          // 将新消息添加到列表
          list.value.unshift(...arr)

          // 将患者卡片重新放回第一位
          if (patientCard) {
            list.value.unshift(patientCard)
          }

          loading.value = false

          if (initialMsg.value && arr.length > 0) {
            // 标记最后一条消息为已读
            await updateMessageStatus(arr[arr.length - 1].id)
            // 第一次需要滚动到最新的消息
            nextTick(() => {
              window.scrollTo(0, document.body.scrollHeight)
              initialMsg.value = false
            })
          }
        } else {
          // 正常轮询时，只添加新消息到末尾
          const newMessages = arr.filter(
            (msg) =>
              !list.value.find((existingMsg) => existingMsg.id === msg.id)
          )

          if (newMessages.length > 0) {
            list.value.push(...newMessages)
            // 标记最后一条新消息为已读
            await updateMessageStatus(newMessages[newMessages.length - 1].id)
            await nextTick()
            window.scrollTo(0, document.body.scrollHeight)
          }
        }
      } else if (loading.value) {
        loading.value = false
        showToast('没有更多聊天记录了')
      }
    } else if (loading.value) {
      loading.value = false
      showToast('没有更多聊天记录了')
    }
  } catch (error) {
    console.error('加载聊天消息失败:', error)
    if (loading.value) {
      loading.value = false
    }
  }
}

// 发送文字信息
const onSendText = async (text: string) => {
  if (!consult.value?.id) return

  try {
    await sendChatMessage({
      orderId: consult.value.id,
      msgType: MsgType.MsgText,
      content: text,
      fromUser: userStore.user?.id,
      toUser: consult.value.docInfo?.id
    })
    // 发送成功后立即获取最新消息
    loadChatMessages()
  } catch (error) {
    console.error('发送文字消息失败:', error)
    showToast('发送失败，请重试')
  }
}

// 发送图片信息
const onSendImage = async (image: Image) => {
  if (!consult.value?.id) return

  try {
    await sendChatMessage({
      orderId: consult.value.id,
      msgType: MsgType.MsgImage,
      picture: image,
      fromUser: userStore.user?.id,
      toUser: consult.value.docInfo?.id
    })
    // 发送成功后立即获取最新消息
    loadChatMessages()
  } catch (error) {
    console.error('发送图片消息失败:', error)
    showToast('发送失败，请重试')
  }
}

// 下拉刷新
const loading = ref(false)
const time = ref(dayjs().format('YYYY-MM-DD HH:mm:ss'))
const onRefresh = () => {
  loading.value = true
  loadChatMessages()
}
</script>

<template>
  <div class="room-page">
    <cp-nav-bar title="问诊室"></cp-nav-bar>
    <!-- 状态栏 -->
    <room-status :status="consult?.status"></room-status>
    <van-pull-refresh v-model="loading" @refresh="onRefresh">
      <!-- 消息 -->
      <room-message
        v-for="item in list"
        :key="item.id"
        :item="item"
      ></room-message>
    </van-pull-refresh>
    <!-- 操作栏 -->
    <room-action
      @send-text="onSendText"
      @send-image="onSendImage"
    ></room-action>
  </div>
</template>

<style lang="scss" scoped>
.room-page {
  padding-top: 90px;
  padding-bottom: 60px;
  min-height: 100vh;
  box-sizing: border-box;
  background-color: var(--cp-bg);
  .van-pull-refresh {
    width: 100%;
    min-height: calc(100vh - 150px);
  }
}
</style>
